目的: 進入聊天室後能夠主動發送商品交易資料(當天特殊交易,ex: 處置交易 or 暫停交易)
# chat/consumers.py
import json
from datetime import datetime
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
from chat.models import Product
from fugle_marketdata import RestClient
#
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.room_name = self.scope["url_route"]["kwargs"]["room_name"]
self.room_group_name = f"chat_{self.room_name}"
client = RestClient(api_key=api_key)
self.stock = client.stock
# Join room group
async_to_sync(self.channel_layer.group_add)(
self.room_group_name, self.channel_name
)
self.accept()
message = f"""
歡迎來到 {self.room_name} 股票即時推播聊天室,
"""
async_to_sync(self.channel_layer.group_send)(
self.room_group_name, {"type": "chat.message", "message": message}
)
# 新加入
obj = Product.objects.filter(symbol=self.room_name).order_by("-date").first()
message = '--------------------------------'
message += f"{obj.date}, {self.room_name} {obj.name}"
if obj.isnormal:
message += '正常交易'
else:
if obj.isattention:
message += '注意股票'
elif obj.isdisposition:
message += '處置股票'
elif obj.ishalted:
message += '暫停股票'
message += '--------------------------------'
async_to_sync(self.channel_layer.group_send)(
self.room_group_name, {"type": "chat.message", "message": message}
)
def disconnect(self, close_code):
# Leave room group
async_to_sync(self.channel_layer.group_discard)(
self.room_group_name, self.channel_name
)
# Receive message from WebSocket
def receive(self, text_data):
text_data_json = json.loads(text_data)
# Receive message from room group
def chat_message(self, event):
message = event["message"]
# Send message to WebSocket
self.send(text_data=json.dumps({"message": message}))
def candles_message(self, event):
message = event["message"]
# Send message to WebSocket
msg = f'現在時間為: {message["date"]}, ' + f','.join([f' {i}: {j}' for i,j in message.items() if i != 'date'])
self.send(text_data=json.dumps({"message": msg}))
目的:進入聊天室的發送訊息
故程式的實作地方在 connect 的地方
然後是在歡迎訊息後顯示股票資訊, 所以會在 "group_send" 之後
obj = Product.objects.filter(symbol=self.room_name).order_by("-date").first()
這段是 django 的取資料語法, 透過 product 這個物件加上篩選條件 symbol=self.room_name, 以及排序BY日期, 這樣就能是最新的一天資料
first() 的意思是取第一筆, 若要取多筆則是 all()
obj.name # 從 obj 的物件中拿取 name 的資訊
最後在填入發送的程式碼
async_to_sync(self.channel_layer.group_send)(
self.room_group_name, {"type": "chat.message", "message": message}
)
大功告成
預期進入可以看到 ( 注意股票)
以及